<template>
  <div id="webgl">光</div>
</template>

<script setup>
import { onMounted } from 'vue'

import * as Three from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
const scene = new Three.Scene()
/**
 * 创建点光源
 * 点光源是从一个点向四面八方发射光线的光源，类似于灯泡
 * 点光源的参数：光的颜色、光的强度、光的距离、光的衰减
 * 光的颜色：光的颜色，可以是十六进制的颜色值，也可以是 CSS3 中的颜色值
 * 光的强度：光的强度，值越大，光的强度越大，光的亮度越高；创建api：new Three.PointLight(color, intensity)
 * 光的距离：光的距离，值越大，光的距离越远，光的影响范围越大；创建api：new Three.PointLight(color, intensity, distance)
 * 光的衰减：光的衰减，值越大，光的衰减越快，光的影响范围越小；创建api：new Three.PointLight(color, intensity, distance, decay)
 * 一般情况下，光的距离和光的衰减是一起设置的，光的距离越大，光的衰减越小，光的影响范围越大
 */
const pointLight = new Three.PointLight('white')
/**
 * 设置光的位置
 * 光的位置是相对于场景的，光的位置决定了光的照射方向
 * 设置光的位置，我们可以通过光的 position  属性来设置，设置原则是：光的位置要能照射到物体
 * 参数：光的位置 x、y、z
 */

// 创建一个点光源
pointLight.position.set(-100, 100, 100)
pointLight.intensity = 2
pointLight.distance = 1000
pointLight.decay = 2

// 创建一个点光源辅助线
const pointLightHelper = new Three.PointLightHelper(pointLight)
scene.add(pointLightHelper)

// 创建一个环境光
const ambientLight = new Three.AmbientLight('white', .4)

// 创建一个平行光
const directionalLight = new Three.DirectionalLight('white', .6)
directionalLight.position.set(0, 0, 100)

// 创建一个辅助线，用来表示光的照射方向
const directionalLightHelper = new Three.DirectionalLightHelper(directionalLight)
scene.add(directionalLightHelper)
/**
 * 创建圆柱体
 * 圆柱体的参数： 圆柱体的底部半径、顶部半径、高度、圆周分段数
 * 圆周分段数（是指将一个圆或圆柱体的圆周划分成的等份的数量）越大，圆柱体的圆周越光滑
 */
const gemoetry = new Three.CylinderGeometry(50, 50, 50, 32)
// const material = new Three.MeshBasicMaterial({ color: 'orange' })
const material = new Three.MeshPhongMaterial({ color: 'orange' })
const mesh = new Three.Mesh(gemoetry, material)
mesh.position.set(0, 0, 0)
scene.add(mesh)
scene.add(pointLight)
scene.add(ambientLight)

directionalLight.target = mesh
scene.add(directionalLight)
/**
 * 创建相机
 * 参数：视角、宽高比、近裁剪面、远裁剪面
 * 视角：相机可见范围的角度，值越大，可见范围越大，但是物体会变小；值越小，可见范围越小，但是物体会变大
 *      一般设置为 45-75 之间，这个值如何设置，取决于你的场景大小和你想要展示的效果
 * 宽高比：视口的宽度和高度比例，一般设置为 canvas 的宽高比
 * 近裁剪面：相机到物体的最小距离，小于这个距离的物体不会被渲染
 * 远裁剪面：相机到物体的最大距离，大于这个距离的物体不会被渲染
 * 二、相机的位置
 * 相机的位置是相对于场景的，相机的位置决定了我们从哪个角度看场景
 * 设置相机的位置，我们可以通过相机的 position 属性来设置，设置原则是：相机的位置要能看到场景中的物体
 * 参数：相机的位置 x、y、z
 * x：相机的水平位置，值越大，相机越靠右；值越小，相机越靠左
 * y：相机的垂直位置，值越大，相机越靠上；值越小，相机越靠下
 * z：相机的深度位置，值越大，相机离物体越远；值越小，相机离物体越近
 * 三、相机的朝向即相机看向哪个方向
 * 相机的朝向是相机的 lookAt 属性来设置的，lookAt 方法接受一个参数，这个参数是一个向量，表示相机看向的方向
 * 通过设置相机的 lookAt 方法，我们可以让相机看向场景中的某个物体
 */
const camera = new Three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 100)
camera.lookAt(0, 0, 0)

/**
 * 创建渲染器
 * 渲染器的作用是将场景和相机结合起来，然后渲染到页面上
 * 1、创建渲染器
 * 2、设置渲染器的大小
 * 3、将渲染器添加到页面中
 * 4、渲染场景
 */
const renderer = new Three.WebGLRenderer()
const width = 800
const height = 800
renderer.setSize(width, height)

onMounted(() => {
  const controls = new OrbitControls(camera, renderer.domElement)
  controls.addEventListener('change', () => renderer.render(scene, camera))
  renderer.render(scene, camera)
  document.getElementById('webgl').appendChild(renderer.domElement)
})
</script>

<style>

</style>